/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package textfilewriter;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.FileUtils;
import textfilewriter.dao.DBProcess;
import textfilewriter.entity.dimension.Customer;
import textfilewriter.entity.dimension.Network;
import textfilewriter.entity.dimension.Portal;
import textfilewriter.entity.dimension.Product;
import textfilewriter.entity.dimension.Service;
import textfilewriter.entity.fact.DataUsage;
import textfilewriter.entity.fact.EcommerceAnalysis;

/**
 *
 * @author GiangLT
 */
public class TextFileWriter {

    private final int LINES_PER_FILE = 300000;
    private final int TOTAL_RECORDS = 900000;
    DBProcess db = new DBProcess();
    List<Customer> customers;

    public TextFileWriter() {
        customers = db.getCustomers();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        TextFileWriter tfw = new TextFileWriter();
//        tfw.createDataUsageFile();
        tfw.createEcommerceAnalysisFile();
//        tfw.updateMsisdn();
    }

    public <T> void createFiles(int linesPerFiles, String filePrefix, List<T> lines) {
        int i = 0;

        while (!lines.isEmpty()) {
            String fileName = "d:/" + filePrefix + "/" + filePrefix + i + ".txt";
            List<T> writeList = new LinkedList<T>();

            int j = 0;
            while (j < linesPerFiles && !lines.isEmpty()) {
                writeList.add(lines.remove(lines.size() - 1));
                j++;
            }
            File file = new File(fileName);
            try {
                FileUtils.writeLines(file, writeList);
                System.out.println("Writen " + linesPerFiles + " lines to " + file.getPath());
            } catch (IOException ex) {
                Logger.getLogger(TextFileWriter.class.getName()).log(Level.SEVERE, null, ex);
            }
            i++;
        }
    }

    public void createDataUsageFile() {

        final double feePerMegabyte = 50.0;
        final int dataUsageVolumeLimit = 10000;

        System.out.println("Fetched " + customers.size() + " customers");
        Random random = new Random();
        List<DataUsage> lines = new ArrayList<DataUsage>();
//        lines.add(DataUsage.getHeader());
        for (int i = 0; i < TOTAL_RECORDS; i++) {
            DataUsage dataUsage = new DataUsage();
            dataUsage.setCustomer(customers.get(random.nextInt(customers.size())));
            int dataUsageVolume = random.nextInt(dataUsageVolumeLimit);
            dataUsage.setDataUsageVolume(dataUsageVolume);
            dataUsage.setFee(dataUsageVolume * feePerMegabyte);
            dataUsage.setNetworkType(random.nextInt(2));

            Date startDate = generateDate();
            dataUsage.setStartDate(startDate);
            final int milisecIn24Hours = 86400000;
            int duration = Math.abs(random.nextInt(milisecIn24Hours));
            dataUsage.setDuration(duration);
            dataUsage.setEndDate(new Date(startDate.getTime() + duration));

            lines.add(dataUsage);
        }
        System.out.println("Filled " + TOTAL_RECORDS + " records");
        createFiles(LINES_PER_FILE, "fact_data_usage", lines);
    }

    public void createEcommerceAnalysisFile() {
        System.out.println("Fetched " + customers.size() + " customers");
        List<Product> products = db.getProducts();
        System.out.println("Fetched " + products.size() + " products");
//        List<Service> services = db.getServices();
//        System.out.println("Fetched " + services.size() + " services");
        List<Network> networks = db.getNetworks();
        System.out.println("Fetched " + networks.size() + " networks");
        List<Portal> portals = db.getPortals();
        System.out.println("Fetched " + portals.size() + " portals");
        Random random = new Random();
        List<EcommerceAnalysis> lines = new ArrayList<EcommerceAnalysis>();
//        lines.add(DataUsage.getHeader());
        for (int i = 0; i < TOTAL_RECORDS; i++) {
            EcommerceAnalysis object = new EcommerceAnalysis();
            object.setCustomer(customers.get(random.nextInt(customers.size())));
            object.setNetwork(networks.get(random.nextInt(networks.size())).getNetworkName());
            object.setPortalUrl(portals.get(random.nextInt(portals.size())).getPortalUrl());
            object.setProductBought(products.get(random.nextInt(products.size())).getProductName());
            object.setRevenue(random.nextInt(200000) + 5000);

            Date startDate = generateDate();
            object.setStartDate(startDate);
            final int milisecIn24Hours = 86400000;
            int duration = Math.abs(random.nextInt(milisecIn24Hours));
//            object.setDuration(duration);
            object.setEndDate(new Date(startDate.getTime() + duration));

            lines.add(object);
        }
        System.out.println("Filled " + TOTAL_RECORDS + " records");
        createFiles(LINES_PER_FILE, "fact_ecommerce_analysis", lines);
    }

    public void updateMsisdn() {
        System.out.println("Fetched " + customers.size() + " customers");
        String[] mdnPrefixes = new String[]{
            "0123", "0166", "090", "092", "098", "091", "0168", "095", "097"
        };
        Random random = new Random();
        for (Customer customer : customers) {
            StringBuilder mdn = new StringBuilder(mdnPrefixes[random.nextInt(9)]);
            for (int i = 0; i < 7; i++) {
                mdn.append(random.nextInt(10));
            }
            db.updateMsisdn(customer.getCustId(), mdn.toString());
        }
    }

    public Date generateDate() {
        Random random = new Random();
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, random.nextInt(4) + 2009);
        cal.set(Calendar.MONTH, random.nextInt(12));
        cal.set(Calendar.DAY_OF_MONTH, random.nextInt(31));
        cal.set(Calendar.HOUR_OF_DAY, random.nextInt(24));
        cal.set(Calendar.MINUTE, random.nextInt(60));
        cal.set(Calendar.SECOND, random.nextInt(60));
        return new Date(cal.getTimeInMillis());
    }

    public Date generateNextDate(Date baseDate, int limit) {
        return new Date(baseDate.getTime() + (new Random().nextInt(limit) + 1000));
    }

    public Date generateNextDate(Date baseDate) {
        return new Date(baseDate.getTime() + (new Random().nextLong() + 1000));
    }
}
